package com.sxjh.config;

import cn.hutool.core.util.StrUtil;
import com.sxjh.common.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MaxUploadSizeExceededException;

/**
 * 全局统一异常处理
 */

@RestControllerAdvice
public class GlobalExceptionHandler {

    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    /**
     * 未捕获的所有异常
     */
    @ExceptionHandler(Exception.class)
    public Result<Void> expHandle(Exception e) {
        log.error(e.getMessage(), e);
        return Result.err("服务内部错误");
    }

    /**
     * 请求参数格式错误
     */
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public Result<Void> expHandle(HttpMessageNotReadableException e) {
        log.error(e.getMessage(), e);
        String msg = e.getMessage();
        int start = msg.indexOf("[\"");
        int end = msg.indexOf("\"]");
        if (start != -1 && end != -1) msg = msg.substring(start + 2, end);
        return Result.err("请求参数格式错误：" + msg);
    }

    /**
     * 自定义校验异常 validation
     */
    @ExceptionHandler(BindException.class)
    public Result<Void> bind(BindException e) {
        log.error(e.getMessage(), e);
        String msg = e.getAllErrors().get(0).getDefaultMessage();
        if (msg.length() > 100) {
            // 参数格式错误
            String msg2 = e.getMessage();
            int start = msg2.indexOf("field '");
            int end = msg2.indexOf("':");
            String filed = msg2.substring(start + 7, end);
            int start2 = msg2.indexOf("value [");
            int end2 = msg2.indexOf("];");
            String value = msg2.substring(start2 + 7, end2);
            if (filed != null && !filed.equals("") && value != null && !value.equals("")) {
                return Result.err("参数'"+ filed +"'格式错误：" + value);
            }
            return Result.err("参数格式错误");
        }
        return Result.err(msg);
    }

    /**
     * 自定义校验异常 validation
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result<Void> expHandle(MethodArgumentNotValidException e) {
        log.error(e.getMessage(), e);
        String msg = e.getAllErrors().get(0).getDefaultMessage();
        return Result.err(msg);
    }

    /**
     * 请求方法错误
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public Result<Void> httpRequestMethodNotSupportedException (HttpRequestMethodNotSupportedException e) {
        String msg = e.getMessage();
        int start = StrUtil.indexOf(msg, '\'');
        int end = StrUtil.lastIndexOf(msg, "'", msg.length(), false);
        msg = msg.substring(start, end + 1);
        log.error(e.getMessage(), e);
        return Result.err("该接口没有 " + msg + " 请求方法");
    }

    /**
     * 自定义异常处理  ResultException
     */
    @ExceptionHandler(ResultException.class)
    public Result<Void> resultException(ResultException e) {
        String msg = e.getMessage();
        return Result.err(msg);
    }

    /**
     * 自定义异常处理
     * ExcelCacheException
     */
    @ExceptionHandler(ExcelCacheException.class)
    public Result<Void> excelCacheException(ExcelCacheException e) {
        return Result.err(e.getMessage());
    }

    /**
     * 登录失效
     */
    @ExceptionHandler(LoseEfficacyException.class)
    public Result<Void> loseEfficacyException(LoseEfficacyException e) {
        return Result.cus(10002, e.getMessage());
    }

    /**
     * 权限异常
     */
    @ExceptionHandler(AuthException.class)
    public Result<Void> authException(AuthException e) {
        return Result.cus(10003, e.getMessage());
    }

    /**
     * 上传文件过大
     */
    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public Result<Void> maxUploadSizeExceededException(MaxUploadSizeExceededException e) {
        return Result.err("上传文件过大");
    }
}